﻿namespace LinqToSqlQueryVisualizer
{
    using System;
    using System.Data;
    using System.Globalization;
    using System.Windows.Forms;

    public partial class QueryVisualizerForm : Form
    {
        private string _connection;

        private SqlQueryText[] _queries;

        private string _sql1; // Sql text for query 1 (may be modified by user)

        private string _sql2; // Sql text for query 2 (may be modified by user)

        private bool _twoQueries;

        private bool _uiInitialized;

        public QueryVisualizerForm()
        {
            InitializeComponent();
        }

        // the sql text for the currently selected query
        private string CurrentSql
        {
            get
            {
                return radioQuery1.Checked ? _sql1 : _sql2;
            }

            set
            {
                if (radioQuery1.Checked)
                {
                    _sql1 = value;
                }
                else
                {
                    _sql2 = value;
                }
            }
        }

        private void OtherSql(string value)
        {
            if (radioQuery1.Checked)
            {
                _sql2 = value;
            }
            else
            {
                _sql1 = value;
            }
        }

        /// <summary>
        /// Sets up this form with the data from the query.
        /// </summary>
        /// <param name="expression">The query as expression text.</param>
        /// <param name="infos">The Sql text and parameter descriptions for the query.</param>
        /// <param name="connectionString">The connectionString string.</param>
        internal void SetTexts(string expression, SqlQueryText[] infos, string connectionString)
        {
            txtExpression.Text = expression;
            _queries = infos;
            _connection = connectionString;
            radioQuery1.Checked = true;
            if (_queries.Length > 1)
            {
                _twoQueries = true;
                radioQuery1.Visible = true;
                radioQuery2.Visible = true;
            }
            else
            {
                _twoQueries = false;
            }

            chkUseOriginal.Checked = false;
            btnQuery.Visible = true;
            InitSqlTexts();
            FillSqlText();
            _uiInitialized = true;
        }

        private void BtnQuery_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            // save current query
            if (!chkUseOriginal.Checked)
            {
                CurrentSql = txtSql.Text;
            }

            // prepare DataSet(s) for the query results
            var ds1 = new DataSet
            {
                Locale = CultureInfo.CurrentUICulture
            };
            var ds2 = new DataSet
            {
                Locale = CultureInfo.CurrentUICulture
            };

            if (chkUseOriginal.Checked)
            {
                QueryExecution.ExecuteOriginalQueries(ds1, ds2, _queries, _connection);
            }
            else if (_twoQueries)
            {
                QueryExecution.ExecuteQueries(ds1, ds2, _sql1, _sql2, _connection);
            }
            else
            {
                QueryExecution.ExecuteQuery(ds1, _sql1, _connection);
            }

            if (_twoQueries)
            {
                var form = new QueryResult2();
                form.SetDataSets(ds1, ds2);
                Cursor = Cursors.Default;
                form.ShowDialog();
            }
            else
            {
                var form = new QueryResult();
                form.SetDataSet(ds1);
                Cursor = Cursors.Default;
                form.ShowDialog();
            }
        }

        private void ChkIncludeParams_CheckedChanged(object sender, EventArgs e)
        {
            if (!_uiInitialized)
            {
                return;
            }

            // save change when new mode is 'use original'
            if (chkUseOriginal.Checked)
            {
                CurrentSql = txtSql.Text;
            }

            txtSql.ReadOnly = chkUseOriginal.Checked;
            FillSqlText();
        }

        /// <summary>
        /// Fills the UI field txtSql
        /// If "original Query" is checked:
        ///   Fill the field txtSql.Text with the appropriate query text and add parameters
        /// Else:
        ///   Fill the text field txtSql.Text with sql.
        /// </summary>
        private void FillSqlText()
        {
            if (chkUseOriginal.Checked)
            {
                var qt = _queries[0];
                if (radioQuery2.Checked)
                {
                    qt = _queries[1];
                }

                var s = qt.Text + "\r\n";
                s += "-------------------------------";
                foreach (var param in qt.Params)
                {
                    if (param.SqlType == "String")
                    {
                        s += "\r\n" + param.Name + " [" + param.SqlType + "]: " + Utils.QuoteString(param.Value);
                    }
                    else
                    {
                        s += "\r\n" + param.Name + " [" + param.SqlType + "]: " + param.Value;
                    }
                }

                txtSql.Text = s;
            }
            else
            {
                txtSql.Text = CurrentSql;
            }
        }

        /// <summary>
        /// Fill sql1 and sql2 with the original sql texts.
        /// </summary>
        private void InitSqlTexts()
        {
            var qt1 = _queries[0];
            _sql1 = Utils.GetQueryTextWithParams(qt1);
            if (!_twoQueries)
            {
                return;
            }

            var qt2 = _queries[1];
            _sql2 = Utils.GetQueryTextWithParams(qt2);
        }

        private void RadioQuery1_CheckedChanged(object sender, EventArgs e)
        {
            if (!_uiInitialized)
            {
                return;
            }

            // save query text
            if (!chkUseOriginal.Checked)
            {
                OtherSql(txtSql.Text);
            }

            FillSqlText();
        }
    }
}